package java8.future;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.reducing;
import static java.util.stream.Collectors.toList;

/**
 * @program JavaBase
 * @description:
 * @author: zhanglu
 * @create: 2020-03-02 13:58:00
 */
public class CompletableFuntureInAction05 {

    public static void main(String[] args) throws InterruptedException {

        /*
            runAfterBoth：两个future执行完毕，才会执行，这个方法块
            allOf：future都执行完毕以后的流式操作
            anyOf：有一个future返回，则执行以后的流式操作
         */


//        CompletableFuture.supplyAsync(() -> {
//            try {
//                Thread.sleep(100);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            System.out.println(Thread.currentThread().getName() + " is running");
//            return 1;
//        }).runAfterBoth(CompletableFuture.supplyAsync(() -> {
//            System.out.println(Thread.currentThread().getName() + " is running");
//            return 2;
//        }), () -> System.out.println("done"));

        /**
            两个方法块都进入，但只会取返回最快的方法的返回结果
            (哪个方法返回快，我用谁，
                例如：同时去 redis01、redis02去查数据，
                先返回的我用哪个，后面就不看了)

             applyToEither：函数型接口
             acceptEither：消费型接口
         */
//        CompletableFuture.supplyAsync(() -> {
//            System.out.println("I am future 1");
//            return CompletableFuntureInAction01.get();
//        }).applyToEither(CompletableFuture.supplyAsync(() -> {
//            System.out.println("I am future 2");
//            return CompletableFuntureInAction01.get();
//        }), v -> v * 10)
//                .thenAccept(System.out::println);
//
//        CompletableFuture.supplyAsync(() -> {
//            System.out.println("I am future 1");
//            return CompletableFuntureInAction01.get();
//        }).acceptEither(CompletableFuture.supplyAsync(() -> {
//            System.out.println("I am future 2");
//            return CompletableFuntureInAction01.get();
//        }), System.out::println);


        List<CompletableFuture<Double>> collect = Arrays.asList(1, 2, 3, 4).stream().map(i -> CompletableFuture.supplyAsync(() -> {
            return CompletableFuntureInAction01.get();
        })).collect(toList());
//        CompletableFuture.allOf(collect.toArray(new CompletableFuture[collect.size()]))
//                .thenRun(() -> System.out.println("done"));


        CompletableFuture.anyOf(collect.toArray(new CompletableFuture[collect.size()]))
                .thenRun(() -> System.out.println("done"));

        Thread.currentThread().join();

    }

}
